﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;

namespace SDF.Primitives
{
    public class LineElement : Canvas
    {
        #region Constructor

        public LineElement(): base()
        {
            CurrentWidth = 0;
            TrailingSpace = 0;
            Height = double.NaN;
        }

        #endregion

        #region Properties

        public double CurrentWidth { get; private set; }

        public double TrailingSpace { get; set; }

        public Point Location
        {
            get { return new Point(Left, Top); }
        }

        public Rect Bounds
        {
            get { return new Rect(Location, new Size(CurrentWidth, Height)); }
        }

        public double Left
        {
            get { return Canvas.GetLeft(this); }
            set { Canvas.SetLeft(this, value); }
        }

        public double Top
        {
            get { return Canvas.GetTop(this); }
            set { Canvas.SetTop(this, value); }
        }

        #endregion

        #region Methods

        public double GetRemainingWidth(double maxWidth)
        { 
            if (double.IsNaN(maxWidth) || double.IsPositiveInfinity(maxWidth))
                return double.PositiveInfinity;

            return Math.Max(0, maxWidth - CurrentWidth - TrailingSpace);
        }

        public void AddInline(InlineElement element, double trailingSpace)
        {
            Canvas.SetLeft(element, CurrentWidth + TrailingSpace);
            Children.Add(element);
            TrailingSpace = trailingSpace;

            AdvanceInsertionPoint(element.Width);
            if (double.IsNaN(this.Height) || (element.Height > this.Height))
            {
                this.Height = element.Height;
            }
        }

        public void AdvanceInsertionPoint(double space)
        {
            if (VisualExtensions.IsGreaterThan(space, 0))
            {
                CurrentWidth += space;
            }
        }

        #endregion

        #region Overriden Methods

        protected override Size ArrangeOverride(Size arrangeSize)
        {
            var size = base.ArrangeOverride(arrangeSize);
            return size;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            double width = CurrentWidth;
            if (!double.IsInfinity(constraint.Width) && (!double.IsNaN(constraint.Width)))
                width = Math.Max(constraint.Width, CurrentWidth);
            if (double.IsNaN(Height))
                return new Size(width, 0);
            else 
                return new Size(width, Height);
        }

        #endregion

        #region GetVisualCopy Method

        public UIElement GetVisualCopy()
        {
            var copy = new Canvas();
            Canvas.SetLeft(copy, Left);

            foreach (InlineElement inline in this.Children)
                copy.Children.Add(inline.GetCopy());

            return copy;
        }

        #endregion

    }
}
